package com.vhly.aapt;

import com.vhly.aapt.io.OrderInputStream;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: vhly[FR]
 * Date: 2010-4-26
 * Time: 15:57:39
 */
public class ResXML {

    public Vector<ResXMLTree_node> nodes;
    public Vector<Integer> resIDs;

    public StringPool pool;


    public String toXML() {
        StringBuffer sb = new StringBuffer();
        String ns = null;
        boolean firstTag = true;
        if(nodes != null && nodes.size() > 0){
            int len = nodes.size();
            ResXMLTree_node node;
            for(int i = 0;i<len;i++){
                node = nodes.elementAt(i);
                if(node instanceof ResXMLTree_namespaceExt){
                    ResXMLTree_namespaceExt namespace = (ResXMLTree_namespaceExt) node;
                    if(!namespace.isEnd){
                        // TODO start
                        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
                        String s1 = pool.entries.elementAt(namespace.prefixStringPoolIndex);
                        String s2 = pool.entries.elementAt(namespace.uriStringPoolIndex);
                        ns = s1+"=\""+s2+"\"";
                    }else{
                        // TODO end not need
                    }
                }else if(node instanceof ResXMLTree_attrExt){
                    // TODO Start
                    ResXMLTree_attrExt el = (ResXMLTree_attrExt) node;
                    if(firstTag){
                        el.ns = ns;
                        firstTag = false;
                    }
                    sb.append(el.toXML());
                }else if(node instanceof ResXMLTree_cdataExt){
                    ResXMLTree_cdataExt cdata = (ResXMLTree_cdataExt) node;
                    sb.append(cdata.toXML());
                }else if(node instanceof ResXMLTree_endElementExt){
                    ResXMLTree_endElementExt end = (ResXMLTree_endElementExt) node;
                    sb.append(end.toXML());
                }
            }
        }
        return sb.toString();
    }


    public void parse(OrderInputStream din) {
        if (din != null) {
            try {
                ResChunkHeader chunk = new ResChunkHeader();
                while (true) {
                    chunk.read(din);
                    System.out.println("chunk.type = " + chunk.type);
                    switch (chunk.type) {
                        case 0x0003:
                            // TODO xml tree start
                            if (nodes == null) {
                                nodes = new Vector<ResXMLTree_node>();
                            } else {
                                nodes.clear();
                            }
                            break;
                        case 0x0001:  // TODO StringPool
                            if (pool == null) {
                                pool = new StringPool();
                            } else {
                                pool.entries.clear();
                            }
                            StringPoolHeader sph = new StringPoolHeader();
                            sph.read(din);
                            int sc = sph.stringCount;
                            int stc = sph.styleCount;
                            if (sc > 0) {
                                for (int i = 0; i < sc; i++) {
                                    pool.indexs.add(din.readInt());
                                }
                                int slen;
                                byte[] buf;
                                for (int i = 0; i < sc; i++) {
                                    slen = din.readShort();
                                    buf = new byte[(slen + 1) << 1];
                                    din.readFully(buf);
                                    pool.entries.add(new String(buf, 0, slen << 1, "UTF-16LE"));
                                }
                            }
                            if (stc > 0) {
                                for (int i = 0; i < stc; i++) {
                                    pool.indexs.add(din.readInt());
                                }
                                int slen;
                                byte[] buf;
                                for (int i = 0; i < stc; i++) {
                                    slen = din.readShort();
                                    buf = new byte[slen << 1];
                                    din.readFully(buf);
                                    pool.entries.add(new String(buf, "UTF-16LE"));
                                }
                            }
                            break;
                        case 0x0180:   // TODO RES_XML_RESOURCE_MAP_TYPE
                            if (resIDs == null) {
                                resIDs = new Vector<Integer>();
                            } else {
                                resIDs.clear();
                            }
                            int clen = (chunk.size - chunk.headerSize) >> 2;
                            for (int i = 0; i < clen; i++) {
                                resIDs.add(din.readInt());
                            }
                            break;
                        case 0x0100:    // TODO RES_XML_START_NAMESPACE_TYPE
                            ResXMLTree_namespaceExt namespace = new ResXMLTree_namespaceExt(false);
                            namespace.pool = pool;
                            namespace.read(din);
                            System.out.println("namespace = " + namespace.lineNumber + " comment " + namespace.commentStringPoolIndex);
                            nodes.add(namespace);
                            break;
                        case 0x101: // TODO RES_XML_END_NAMESPACE_TYPE
                            ResXMLTree_namespaceExt namespace1 = new ResXMLTree_namespaceExt(true);
                            namespace1.pool = pool;
                            namespace1.read(din);
                            System.out.println("namespace = " + namespace1.lineNumber + " comment " + namespace1.commentStringPoolIndex);
                            nodes.add(namespace1);
                            break;
                        case 0x0102:  // TODO RES_XML_START_ELEMENT_TYPE
                            ResXMLTree_attrExt el = new ResXMLTree_attrExt();
                            el.pool = pool;
                            el.read(din);
                            nodes.add(el);
                            int an = el.attributeCount;
                            el.attributes.clear();
                            ResXMLTree_attribute attr;
                            for (int i = 0; i < an; i++) {
                                attr = new ResXMLTree_attribute();
                                attr.pool = pool;
                                attr.read(din);
                                el.attributes.add(attr);
                            }
                            break;
                        case 0x103:    // TODO RES_XML_END_ELEMENT_TYPE
                            ResXMLTree_endElementExt end = new ResXMLTree_endElementExt();
                            end.pool = pool;
                            end.read(din);
                            nodes.add(end);
                            break;
                        case 0x104:      // TODO RES_XML_CDATA_TYPE
                            ResXMLTree_cdataExt cdata = new ResXMLTree_cdataExt();
                            cdata.pool = pool;
                            cdata.read(din);
                            nodes.add(cdata);
                            break;
                        case 0x200:
                            System.out.println("break me");
                            break;
                        case 0x201:
                            System.out.println("break me");
                            break;
                        case 0x202:
                            System.out.println("break me");
                            break;
                        case 0x02:
                            System.out.println("break me");
                            break;
                    }
                }
            } catch (IOException ioe) {

            }
        }
    }
}
